package com.cgc.venus.server.job.jobdetail;
import com.cgc.venus.server.core.utils.SpringUtil;
import com.cgc.venus.server.job.bean.SendAlarm;
import com.cgc.venus.server.job.config.JobConfig;
import com.cgc.venus.server.job.inter.EmailService;
import com.cgc.venus.server.job.inter.SmService;
import com.cgc.venus.server.job.service.EmailServiceImpl;
import com.cgc.venus.server.job.service.SmServiceImpl;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 预警处理任务
 */
public class AlarmJob extends AbstractBaseJob {
    private static Logger logger = LoggerFactory.getLogger(AlarmJob.class);
    public AlarmJob() {
    }
    public void execute(JobExecutionContext context)  
        throws JobExecutionException {
        logger.info("预警处理job start...");
        //预警触发条件
        // (1) 表 t_job_alarm 当天含有状态为未处理的数据.
        // (2) 所有job有error状态的情况
        List<SendAlarm> sendAlarms=new ArrayList<>();
        String sql="";
        List<Map<String, Object>> r=null;
        String [] phones=null;//平台级别的手机号码集合
        String [] emailAddress=null;//平台级别的邮件地址集合
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now=sdf.format(new Date());
        //获取平台级别的 邮件和短信对象
        sql="SELECT group_concat(DISTINCT u.phone) phones, group_concat(DISTINCT u.email) emails FROM t_user u JOIN t_role r ON u.role = r.id WHERE r.is_superadmin = 1";
        r=this.getJdbcTemplate().queryForList(sql);
        phones=r.get(0).get("phones").toString().split(",");
        emailAddress=r.get(0).get("emails").toString().split(",");

        //收集预警信息start
        //预警触发条件(1)的处理
            //处理逻辑
            //查询预警表当天未发送信息的预警信息
            //发送预警信息(邮件和短信)
            //将信息改为已经处理
            try {
                //平台级别的告警信息的处理 start
                //> 查询
                //sql="SELECT am.Alarm_type alarmType, group_concat(DISTINCT am.id) ids, group_concat(DISTINCT am.Alarm_msg, '$$') msg FROM t_job_alarm am WHERE am.Ns_name = 'all' AND am.`status` = 0 AND date_format(create_time, '%Y-%m-%d') = date_format(NOW(), '%Y-%m-%d') GROUP BY am.Alarm_type";
                sql="SELECT am.Alarm_type alarmType,COUNT(am.id) ids,group_concat(DISTINCT am.Alarm_msg, '$$') msg FROM t_job_alarm am WHERE am.Ns_name = 'all' AND am.`status` = 0 AND date_format(create_time, '%Y-%m-%d') = date_format(NOW(), '%Y-%m-%d') GROUP BY am.Alarm_type";
                r=this.getJdbcTemplate().queryForList(sql);
                //> 信息更改为已处理
                this.getJdbcTemplate().update("update t_job_alarm am set am.`status`=1 WHERE am.Ns_name = 'all' AND am.`status` = 0 AND date_format(create_time, '%Y-%m-%d') = date_format(NOW(), '%Y-%m-%d')");
                if(r!=null&&r.size()>0){
//                    String smMsg="平台告警信息:\r\n";
//                    String emailMsg="平台告警信息:\r\n";
                    String smMsg="";
                    String emailMsg="";
                    int alarmType=0;
                    for(Map<String, Object> map:r){
                        alarmType= (int) map.get("alarmType");
                        //smMsg+=convertAlarmType(alarmType)+":"+map.get("ids").toString()+"\r\n";
                        smMsg+=convertAlarmType(alarmType)+":"+map.get("msg").toString()+"\r\n";//也发明细信息
                        emailMsg+=convertAlarmType(alarmType)+":"+map.get("msg").toString()+"\r\n";
                    }
                    smMsg+=",请及时处理!"+now;
                    emailMsg+=",请及时处理!"+now;
                    sendAlarms.add(new SendAlarm(smMsg,0,phones));
                    sendAlarms.add(new SendAlarm(emailMsg,1,emailAddress));
                }
                //平台级别的告警信息的处理 end
            }catch (Exception ex){
                logger.error(ex.getMessage(),ex);
            }

            try {
                //空间级别的告警信息的处理 start
                sql="SELECT am.Ns_name, ns.`name`,count(DISTINCT am.id) ids,group_concat(DISTINCT am.Alarm_msg, '$$') msg, group_concat(DISTINCT u.phone) phones, group_concat(DISTINCT u.email) emails FROM t_job_alarm am LEFT JOIN t_namespace ns ON ns.kube_name = am.Ns_name LEFT JOIN t_namespace_user nu ON nu.namespace = ns.id LEFT JOIN t_user u ON u.id = nu.`user` WHERE am.Ns_name != 'all' AND am.`status` = 0 AND ns.kube_name != '' AND date_format(am.create_time, '%Y-%m-%d') = date_format(NOW(), '%Y-%m-%d') GROUP BY am.Ns_name, ns.kube_name";
                r=this.getJdbcTemplate().queryForList(sql);
                this.getJdbcTemplate().update("update t_job_alarm am set am.`status`=1 WHERE am.Ns_name != 'all' AND am.`status` = 0 AND date_format(am.create_time, '%Y-%m-%d') = date_format(NOW(), '%Y-%m-%d')");
                if(r!=null&&r.size()>0){
                    for(Map<String, Object> map:r){
//                        String msg="平台告警信息:\r\n";
                        String msg="";
                        msg+=map.get("name").toString()+":"+map.get("msg").toString()+"\r\n";
                        msg+=",请及时处理!"+now;
                        if(map.get("phones")!=null){
                            sendAlarms.add(new SendAlarm(msg,0,map.get("phones").toString().split(",")));
                        }
                        if(map.get("emails")!=null){
                            sendAlarms.add(new SendAlarm(msg,1,map.get("emails").toString().split(",")));
                        }

                    }
                }
                //空间级别的告警信息的处理 end
            }catch (Exception ex){
                logger.error(ex.getMessage(),ex);
            }

        //预警触发条件(2)的处理
        try{
            sql="SELECT job.JOB_NAME jobName, qt.TRIGGER_STATE jobStatus FROM qrtz_job_details job JOIN qrtz_triggers qt JOIN qrtz_cron_triggers qct ON job.JOB_NAME = qt.JOB_NAME AND qt.TRIGGER_NAME = qct.TRIGGER_NAME AND qt.TRIGGER_GROUP = qct.TRIGGER_GROUP WHERE qt.TRIGGER_STATE = 'ERROR'";
            r=this.getJdbcTemplate().queryForList(sql);
            if(r!=null&&r.size()>0){
                //任务{统计xxx}{统计xxx}出现异常,请及时处理!
                String msg="任务:";
                for(Map<String, Object> map:r){
                    msg+="{"+map.get("jobName").toString()+"}";
                }
                msg+="出现异常,请及时处理!";
                sendAlarms.add(new SendAlarm(msg,0,phones));
                sendAlarms.add(new SendAlarm(msg,1,emailAddress));
            }
        }catch (Exception ex){
            logger.error(ex.getMessage(),ex);
        }
        //收集预警信息end


        if(sendAlarms.size()>0){
            try {
                JobConfig jobConfig=SpringUtil.getBean(JobConfig.class);
                EmailService emailService= SpringUtil.getBean(EmailServiceImpl.class);
                SmService smService=SpringUtil.getBean(SmServiceImpl.class);
                List<SendAlarm> sendSmAlarms=sendAlarms.stream().filter(ts -> 0==ts.getSendMsgType()).collect(Collectors.toList());
                List<SendAlarm> sendEmailAlarms=sendAlarms.stream().filter(ts -> 1==ts.getSendMsgType()).collect(Collectors.toList());
                //发送短信
                try {
                    if(jobConfig.isSmEnable()){
                        int i=1;
                        for(SendAlarm sendAlarm:sendSmAlarms){
                            smService.sendShortMessage(sendAlarm.getSendObject(),sendAlarm.getAlarmMsg(),jobConfig.getSmTopic());
                            logger.info("本次任务成功发送"+i+"条告警短信!");
                            i++;
                        }
                    }
                }catch (Exception e){
                    logger.error("发送短信异常!");
                }

                //发送邮件
                try {
                    if(jobConfig.isEmailEnable()){
                        int i=1;
                        for(SendAlarm sendAlarm:sendEmailAlarms){
                            emailService.sendEmailByText(sendAlarm.getSendObject(),jobConfig.getSmTopic()+"告警通知!",sendAlarm.getAlarmMsg());
                            logger.info("本次任务成功发送"+i+"封告警邮件!");
                            i++;
                        }
                    }
                }catch (Exception e){
                    logger.error("发送邮件异常!");
                }
            }catch (Exception e){
                logger.error(e.getMessage(),e);
            }
        }else{
            logger.info("本次定时任务未查询到预警信息!");
        }
    }

    private String convertAlarmType(int alarmType){
//        public static final int ALARM_TYPE_JOB_ERROR=0;//job错误告警
//        public static final int ALARM_TYPE_NODE=1;//平台节点告警
//        public static final int ALARM_TYPE_APP=2;//平台应用告警
//        public static final int ALARM_TYPE_STORAGE=3;//平台存储告警
//        public static final int ALARM_TYPE_NS_APP=4;//平台空间应用告警
//        public static final int ALARM_TYPE_HEALTH=5;//平台健康告警
        if(alarmType==0){
            return "job异常";
        }
        if(alarmType==1){
            return "节点异常";
        }
        if(alarmType==2){
            return "应用异常";
        }
        if(alarmType==3){
            return "存储异常";
        }
        if(alarmType==4){
            return "空间应用异常";
        }
        if(alarmType==5){
            return "平台健康异常";
        }
        return "未知异常";
    }

}